#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
LeetCode 134 加油站问题测试程序
使用gen.py生成的测试数据来验证算法的正确性
"""

import time
import sys
from alg import Solution
from gen import generate_test_cases, generate_edge_cases, generate_random_test_case

class TestRunner:
    def __init__(self):
        self.solution = Solution()
        self.passed = 0
        self.failed = 0
        self.total_time = 0
    
    def run_single_test(self, test_case, show_details=True):
        """运行单个测试用例"""
        name = test_case["name"]
        gas = test_case["gas"]
        cost = test_case["cost"]
        expected = test_case["expected"]
        description = test_case["description"]
        
        if show_details:
            print(f"\n{'='*60}")
            print(f"测试用例: {name}")
            print(f"描述: {description}")
            print(f"gas:  {gas}")
            print(f"cost: {cost}")
            print(f"期望结果: {expected}")
        
        # 执行测试并计时
        start_time = time.time()
        try:
            result = self.solution.canCompleteCircuit(gas, cost)
            end_time = time.time()
            execution_time = (end_time - start_time) * 1000  # 转换为毫秒
            self.total_time += execution_time
            
            # 检查结果
            if expected is None:
                # 对于随机测试用例，我们无法预知答案，只验证算法不崩溃
                print(f"实际结果: {result}")
                print(f"执行时间: {execution_time:.2f} ms")
                print("✓ 算法执行成功（随机测试用例）")
                self.passed += 1
                return True
            elif result == expected:
                if show_details:
                    print(f"实际结果: {result}")
                    print(f"执行时间: {execution_time:.2f} ms")
                    print("✓ 测试通过")
                self.passed += 1
                return True
            else:
                if show_details:
                    print(f"实际结果: {result}")
                    print(f"执行时间: {execution_time:.2f} ms")
                    print("✗ 测试失败")
                self.failed += 1
                return False
                
        except Exception as e:
            end_time = time.time()
            execution_time = (end_time - start_time) * 1000
            self.total_time += execution_time
            if show_details:
                print(f"✗ 测试出错: {str(e)}")
                print(f"执行时间: {execution_time:.2f} ms")
            self.failed += 1
            return False
    
    def verify_result_manually(self, gas, cost, start_idx):
        """手动验证结果的正确性"""
        if start_idx == -1:
            # 验证确实无解
            total_gas = sum(gas)
            total_cost = sum(cost)
            return total_gas < total_cost
        
        # 验证从start_idx出发确实可以走一圈
        n = len(gas)
        current_gas = 0
        
        for i in range(n):
            station = (start_idx + i) % n
            current_gas += gas[station] - cost[station]
            if current_gas < 0:
                return False
        return True
    
    def run_basic_tests(self):
        """运行基本测试用例"""
        print("🚗 开始运行基本测试用例...")
        basic_cases = generate_test_cases()
        
        for case in basic_cases:
            self.run_single_test(case)
    
    def run_edge_tests(self):
        """运行边界测试用例"""
        print("\n🎯 开始运行边界测试用例...")
        edge_cases = generate_edge_cases()
        
        for case in edge_cases:
            self.run_single_test(case)
    
    def run_random_tests(self, count=5):
        """运行随机测试用例"""
        print(f"\n🎲 开始运行 {count} 个随机测试用例...")
        
        for i in range(count):
            size = [5, 10, 15, 20, 25][i % 5]
            case = generate_random_test_case(size, max_val=50)
            result = self.run_single_test(case, show_details=False)
            print(f"随机测试 {i+1}/{count}: {'✓' if result else '✗'}")
    
    def run_performance_test(self):
        """运行性能测试"""
        print("\n⚡ 开始性能测试...")
        
        # 测试不同规模的性能
        sizes = [10, 50, 100, 500, 1000]
        
        for size in sizes:
            print(f"\n测试规模: {size} 个加油站")
            
            # 生成测试数据
            case = generate_random_test_case(size, max_val=1000)
            
            # 多次运行取平均值
            times = []
            for _ in range(5):
                start_time = time.time()
                self.solution.canCompleteCircuit(case["gas"], case["cost"])
                end_time = time.time()
                times.append((end_time - start_time) * 1000)
            
            avg_time = sum(times) / len(times)
            print(f"平均执行时间: {avg_time:.2f} ms")
            
            # 分析时间复杂度
            if size <= 100:
                print(f"时间复杂度表现: 优秀")
            elif avg_time < size * 0.1:
                print(f"时间复杂度表现: 良好")
            else:
                print(f"时间复杂度表现: 需要优化")
    
    def run_all_tests(self):
        """运行所有测试"""
        print("🚀 开始运行完整测试套件...")
        print("="*60)
        
        start_time = time.time()
        
        # 运行各类测试
        self.run_basic_tests()
        self.run_edge_tests()
        self.run_random_tests()
        self.run_performance_test()
        
        end_time = time.time()
        total_execution_time = end_time - start_time
        
        # 输出总结
        print("\n" + "="*60)
        print("📊 测试结果总结")
        print("="*60)
        print(f"通过测试: {self.passed}")
        print(f"失败测试: {self.failed}")
        print(f"总测试数: {self.passed + self.failed}")
        print(f"成功率: {self.passed/(self.passed + self.failed)*100:.1f}%")
        print(f"总执行时间: {total_execution_time:.2f} 秒")
        print(f"平均算法执行时间: {self.total_time/(self.passed + self.failed):.2f} ms")
        
        if self.failed == 0:
            print("🎉 所有测试都通过了！")
        else:
            print(f"⚠️  有 {self.failed} 个测试失败，请检查算法实现")
        
        return self.failed == 0

def main():
    """主函数"""
    if len(sys.argv) > 1:
        test_type = sys.argv[1]
    else:
        test_type = "all"
    
    runner = TestRunner()
    
    if test_type == "basic":
        runner.run_basic_tests()
    elif test_type == "edge":
        runner.run_edge_tests()
    elif test_type == "random":
        runner.run_random_tests(10)
    elif test_type == "performance":
        runner.run_performance_test()
    elif test_type == "all":
        runner.run_all_tests()
    else:
        print("使用方法: python test.py [basic|edge|random|performance|all]")
        return
    
    # 最终统计
    total_tests = runner.passed + runner.failed
    if total_tests > 0:
        print(f"\n最终结果: {runner.passed}/{total_tests} 个测试通过")

if __name__ == "__main__":
    main()